home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
strategy
/
vga_card.000
/
vga_cardgames-1.3.1.tar
/
vga_cardgames
/
ohhell.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-05
|
10KB
|
454 lines
/*
* Oh Hell!
*
* Copyright (C) Evan Harris, 1991, 1993, 1994
*
* Permission is granted to freely redistribute and modify this code,
* providing the author(s) get credit for having written it.
*/
#include <stdlib.h>
#ifdef PRINTPROGRESS
#include <stdio.h>
#endif
#include "ohhell.h"
unsigned char hand[NUMPLAYERS][NUMHANDS];
unsigned char bid[NUMPLAYERS];
unsigned char wins[NUMPLAYERS];
unsigned char score[NUMPLAYERS];
unsigned char played[NUMPLAYERS];
unsigned char trumps;
unsigned char led;
void
main(int argc, char **argv)
{
unsigned char deal = 1;
unsigned char first = 0;
InitDisplay(argc, argv);
InitRandom(NEW);
InitGame();
for (;;) {
switch (PlayGame(deal, first)) {
case NEWGAME:
InitGame();
deal = 1;
first = (first + 1) % NUMPLAYERS;
break;
case NEXTGAME:
deal++;
first = (first + 1) % NUMPLAYERS;
break;
case QUIT:
EndDisplay();
exit(0);
break;
}
}
}
void
InitGame()
{
unsigned char i;
for (i = 0; i < NUMPLAYERS; i++)
score[i] = 0;
ShowScores(score);
return;
}
short
PlayGame(unsigned char deal, unsigned char first)
{
unsigned char i, j;
short b, best;
short key;
short cmd;
unsigned char lead = first;
if (deal > NUMHANDS) {
do {
cmd = GetCmd();
}
while (cmd != NEWGAME && cmd != QUIT);
return cmd;
}
trumps = Deal(deal);
for (i = 0; i < NUMPLAYERS; i++) {
wins[i] = 0;
}
ShowWins(wins);
RemoveBids();
for (i = first; i < first + NUMPLAYERS; i++) {
b = GetBid(i % NUMPLAYERS, deal, first);
if (b == NEWGAME || b == QUIT) return b;
bid[i % NUMPLAYERS] = b;
ShowBid(bid[i % NUMPLAYERS], i % NUMPLAYERS);
}
for (i = 0; i < deal; i++) {
for (j = 0; j < NUMPLAYERS; j++) {
played[j] = NOCARD;
}
led = NOCARD;
for (j = lead; j < lead + NUMPLAYERS; j++) {
b = GetPlay(j % NUMPLAYERS, deal, lead);
if (b == NEWGAME || b == QUIT) return b;
ShowPlay(b, j % NUMPLAYERS);
if (j % NUMPLAYERS == 0)
ShowHand(hand[0], deal);
played[j % NUMPLAYERS] = b;
if (led == NOCARD)
led = b;
}
best = -1;
for (j = lead; j < lead + NUMPLAYERS; j++) {
if (best == -1 ||
(SUIT(played[j % NUMPLAYERS]) == SUIT(played[best]) &&
(TYPE(played[j % NUMPLAYERS]) + 12) % 13 >
(TYPE(played[best]) + 12) % 13) ||
(SUIT(played[j % NUMPLAYERS]) == trumps &&
SUIT(played[best]) != trumps)) {
best = j % NUMPLAYERS;
}
}
wins[best]++;
lead = best;
ShowWins(wins);
key = WaitForKey();
RemovePlays();
if (key != CONTINUE)
return key;
}
for (i = 0; i < NUMPLAYERS; i++) {
if (wins[i] == bid[i])
score[i] += 10 + bid[i];
}
ShowScores(score);
return NEXTGAME;
}
unsigned char
Deal(unsigned char deal)
{
unsigned char cards[NUMCARDS];
unsigned char i, j, k;
short r;
for (i = 0; i < NUMCARDS; i++) {
cards[i] = 0;
}
for (i = 0; i < deal; i++) {
for (j = 0; j < NUMPLAYERS; j++) {
r = Random(NUMCARDS - (i * NUMPLAYERS + j));
for (k = 0; k < NUMCARDS && r >= 0; k++) {
if (cards[k] == 0)
r--;
}
r = k - 1;
cards[r] = 1;
hand[j][i] = r;
}
}
if (deal * NUMPLAYERS < NUMCARDS) {
r = Random(NUMCARDS - deal * NUMPLAYERS);
for (k = 0; k < NUMCARDS && r >= 0; k++) {
if (cards[k] == 0)
r--;
}
trumps = k - 1;
ShowTrumps(trumps);
trumps = SUIT(trumps);
}
else {
RemoveTrumps();
trumps = NOSUIT;
}
qsort(hand[0], deal, sizeof(unsigned char), (__compar_fn_t)&Cmp);
ShowHand(hand[0], deal);
return trumps;
}
short
GetBid(unsigned char player, unsigned char deal, unsigned char first)
{
short bid = 0;
unsigned char i, numtrumps = 0;
if (player == 0)
return GetPlayerBid(deal);
for (i = 0; i < deal; i++) {
if (TYPE(hand[player][i]) == ACE || TYPE(hand[player][i]) == KING ||
TYPE(hand[player][i]) == QUEEN)
bid++;
else if (SUIT(hand[player][i]) == trumps)
numtrumps++;
}
if (deal < 4 && player == first)
bid++;
if (numtrumps > deal / 4)
bid += numtrumps - deal / 4;
if (bid > deal)
bid = deal;
return bid;
}
short
GetPlay(unsigned char player, unsigned char deal, unsigned char first)
{
#ifdef PRINTPROGRESS
static char suits[] = { 's', 'c', 'h', 'd' };
static char types[] = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
#endif
short cmd = NOCARD, ret;
unsigned char i;
unsigned char best = NOCARD;
unsigned char wanttowin;
unsigned char winning;
short smallestwinner, biggestwinner, smallestloser, biggestloser;
unsigned char legal[NUMCARDS / NUMPLAYERS];
unsigned char numlegal;
unsigned char under, over, equal;
if (player == 0) {
while (cmd == NOCARD) {
#if 0
FlushIn();
#endif
cmd = GetCmd();
if (cmd < 0)
return cmd;
else if (led != NOCARD &&
SUIT(hand[player][cmd]) != SUIT(led)) {
for (i = 0; i < deal; i++)
if (hand[player][i] != NOCARD &&
SUIT(hand[player][i]) == SUIT(led))
cmd = NOCARD;
}
}
ret = hand[player][cmd];
hand[player][cmd] = NOCARD;
return ret;
}
#ifdef PRINTPROGRESS
if (led == NOCARD) fprintf(stderr, "\n");
fprintf(stderr, "Player %d : ", player);
for (i = 0; i < deal; i++)
if (hand[player][i] != NOCARD)
fprintf(stderr, "%c%c ", types[TYPE(hand[player][i])],
suits[SUIT(hand[player][i])]);
#endif
if (led != NOCARD) {
/*
* Find which card that has been played is winning.
*/
winning = led;
for (i = (first + 1) % NUMPLAYERS;
i != player;
i = (i + 1) % NUMPLAYERS) {
if ((SUIT(played[i]) == SUIT(winning)
&& TYPECMP(played[i], winning) > 0) ||
(SUIT(played[i]) == trumps && SUIT(winning) != trumps))
winning = played[i];
}
/*
* Find all the legal cards. First a pass looking for suit cards.
*/
numlegal = 0;
for (i = 0; i < deal; i++) {
if (hand[player][i] != NOCARD
&& SUIT(hand[player][i]) == SUIT(led)) {
legal[numlegal] = i;
numlegal++;
}
}
#ifdef PRINTPROGRESS
fprintf(stderr, " legal : %d ", numlegal);
#endif
smallestloser = biggestloser = smallestwinner = biggestwinner = -1;
if (numlegal > 0) {
/*
* Look amongst suit cards for all winners and losers.
*/
for (i = 0; i < numlegal; i++) {
if ((SUIT(led) == trumps || SUIT(winning) != trumps) &&
TYPECMP(winning, hand[player][legal[i]]) < 0) {
if (smallestwinner == -1)
smallestwinner = biggestwinner = legal[i];
else if (TYPECMP(hand[player][smallestwinner],
hand[player][legal[i]]) > 0)
smallestwinner = legal[i];
else if (TYPECMP(hand[player][biggestwinner],
hand[player][legal[i]]) < 0)
biggestwinner = legal[i];
} else {
if (smallestloser == -1)
smallestloser = biggestloser = legal[i];
else if (TYPECMP(hand[player][smallestloser],
hand[player][legal[i]]) > 0)
smallestloser = legal[i];
else if (TYPECMP(hand[player][biggestloser],
hand[player][legal[i]]) < 0)
biggestloser = legal[i];
}
}
} else {
/*
* Look amongst all cards for winners (trumps) and losers (others).
*/
for (i = 0; i < deal; i++) {
if (hand[player][i] != NOCARD) {
if (SUIT(hand[player][i]) == trumps &&
(SUIT(winning) != trumps
|| TYPECMP(winning, hand[player][i]) < 0)) {
if (smallestwinner == -1)
smallestwinner = biggestwinner = i;
else if (TYPECMP(hand[player][smallestwinner],
hand[player][i]) > 0)
smallestwinner = i;
else if (TYPECMP(hand[player][biggestwinner],
hand[player][i]) < 0)
biggestwinner = i;
}
else {
if (smallestloser == -1)
smallestloser = biggestloser = i;
else if ((SUIT(hand[player][smallestloser]) == trumps
&& SUIT(hand[player][i]) != trumps)
|| TYPECMP(hand[player][smallestloser],
hand[player][i]) > 0)
smallestloser = i;
else if ((SUIT(hand[player][smallestloser]) != trumps
&& SUIT(hand[player][i]) == trumps)
|| TYPECMP(hand[player][biggestloser],
hand[player][i]) < 0)
biggestloser = i;
}
}
}
}
}
under = over = equal = 0;
for (i = 0; i < NUMPLAYERS; i++) {
if (i != player) {
if (wins[player] < bid[player])
under++;
else if (wins[player] > bid[player])
over++;
else
equal++;
}
}
if (wins[player] < bid[player])
wanttowin = TRUE;
else
wanttowin = FALSE;
if (led == NOCARD) {
for (i = 0; i < deal; i++) {
if (hand[player][i] != NOCARD) {
if (best == NOCARD ||
(wanttowin &&
TYPECMP(hand[player][best], hand[player][i]) < 0) ||
(!wanttowin &&
TYPECMP(hand[player][best], hand[player][i]) > 0))
best = i;
}
}
}
else {
#ifdef PRINTPROGRESS
if (smallestloser != -1)
fprintf(stderr, " sl : %c%c",
types[TYPE(hand[player][smallestloser])],
suits[SUIT(hand[player][smallestloser])]);
if (biggestloser != -1)
fprintf(stderr, " bl : %c%c",
types[TYPE(hand[player][biggestloser])],
suits[SUIT(hand[player][biggestloser])]);
if (smallestwinner != -1)
fprintf(stderr, " sw : %c%c",
types[TYPE(hand[player][smallestwinner])],
suits[SUIT(hand[player][smallestwinner])]);
if (biggestwinner != -1)
fprintf(stderr, " bw : %c%c ",
types[TYPE(hand[player][biggestwinner])],
suits[SUIT(hand[player][biggestwinner])]);
#endif
if (wanttowin) {
if (smallestwinner != -1) {
if (player == (first - 1 + NUMPLAYERS) % NUMPLAYERS)
best = smallestwinner;
else
best = biggestwinner;
}
else
best = smallestloser;
}
else {
if (biggestloser != -1)
best = biggestloser;
else if (equal >= under)
best = smallestwinner;
else
best = biggestwinner;
}
}
#ifdef PRINTPROGRESS
fprintf(stderr, " playing : %c%c\n", types[TYPE(hand[player][best])],
suits[SUIT(hand[player][best])]);
#endif
ret = hand[player][best];
hand[player][best] = NOCARD;
return ret;
}
int Cmp(unsigned char *a, unsigned char *b)
{
static unsigned char remap[4] = { 0, 2, 1, 3 };
unsigned char arank = CARD(remap[SUIT(*a)], (TYPE(*a) + 12) % 13);
unsigned char brank = CARD(remap[SUIT(*b)], (TYPE(*b) + 12) % 13);
if (arank < brank) return 1;
if (arank > brank) return -1;
return 0;
}